import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "../trpc";

// 更新状态枚举定义
const TaskStatus = {
  NOT_STARTED: "NOT_STARTED",
  IN_PROGRESS: "IN_PROGRESS",
  COMPLETED: "COMPLETED",
} as const;

const taskSchema = z.object({
  title: z.string().min(1, "任务标题不能为空"),
  description: z.string().optional(),
  dueDate: z.date().optional(),
  status: z.enum(["NOT_STARTED", "IN_PROGRESS", "COMPLETED"]).default("NOT_STARTED"),
  priority: z.enum(["LOW", "MEDIUM", "HIGH"]).default("MEDIUM"),
  courseId: z.string(),
  steps: z.array(z.object({
    title: z.string().min(1, "步骤标题不能为空"),
    description: z.string().optional(),
    orderIndex: z.number(),
  })).optional(),
});

export const tasksRouter = createTRPCRouter({
  // 获取任务列表
  list: protectedProcedure
    .input(
      z.object({
        courseId: z.string(),
        page: z.number().min(1).default(1),
        pageSize: z.number().min(1).default(10),
        status: z.enum(["TODO", "IN_PROGRESS", "COMPLETED", "ALL"]).optional(),
      })
    )
    .query(async ({ ctx, input }) => {
      const { courseId, page, pageSize, status } = input;
      const where = {
        courseId,
        ...(status && status !== "ALL" ? { status } : {}),
      };

      const [total, items] = await Promise.all([
        ctx.db.task.count({ where }),
        ctx.db.task.findMany({
          where,
          skip: (page - 1) * pageSize,
          take: pageSize,
          include: {
            creator: {
              select: {
                id: true,
                name: true,
              },
            },
          },
          orderBy: {
            createdAt: "desc",
          },
        }),
      ]);

      return {
        items,
        total,
        page,
        pageSize,
        totalPages: Math.ceil(total / pageSize),
      };
    }),

  // 创建任务
  create: protectedProcedure
    .input(z.object({
      title: z.string().min(1, "标题不能为空"),
      description: z.string().optional(),
      content: z.string().optional(),
      dueDate: z.date().optional(),
      status: z.enum(["NOT_STARTED", "IN_PROGRESS", "COMPLETED"]),
      priority: z.enum(["LOW", "MEDIUM", "HIGH"]),
      courseId: z.string(),
      steps: z.array(z.object({
        title: z.string(),
        description: z.string().optional(),
        orderIndex: z.number(),
      })).optional(),
    }))
    .mutation(async ({ ctx, input }) => {
      const { steps, ...taskData } = input;

      return ctx.db.$transaction(async (tx) => {
        const task = await tx.task.create({
          data: {
            ...taskData,
            createdBy: ctx.session.user.id,
          },
        });

        if (steps?.length) {
          await tx.step.createMany({
            data: steps.map((step) => ({
              ...step,
              taskId: task.id,
            })),
          });
        }

        return task;
      });
    }),

  // 更新任务
  update: protectedProcedure
    .input(z.object({
      id: z.string(),
      data: taskSchema.partial(),
    }))
    .mutation(async ({ ctx, input }) => {
      const { id, data: { steps, ...taskData } } = input;

      return ctx.db.$transaction(async (tx) => {
        const task = await tx.task.update({
          where: { id },
          data: taskData,
        });

        if (steps) {
          await tx.step.deleteMany({
            where: { taskId: id },
          });

          await tx.step.createMany({
            data: steps.map((step) => ({
              ...step,
              taskId: id,
            })),
          });
        }

        return task;
      });
    }),

  // 删除任务
  delete: protectedProcedure
    .input(z.string())
    .mutation(async ({ ctx, input }) => {
      const task = await ctx.db.task.findUnique({
        where: { id: input },
      });

      if (!task) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "任务不存在",
        });
      }

      if (
        task.createdBy !== ctx.session.user.id &&
        ctx.session.user.role !== "ADMIN"
      ) {
        throw new TRPCError({
          code: "FORBIDDEN",
          message: "没有权限删除此任务",
        });
      }

      return ctx.db.task.delete({
        where: { id: input },
      });
    }),

  // 获取任务步骤
  getWithSteps: protectedProcedure
    .input(z.object({
      taskId: z.string(),
    }))
    .query(async ({ ctx, input }) => {
      const task = await ctx.db.task.findUnique({
        where: { id: input.taskId },
        include: {
          steps: {
            orderBy: {
              orderIndex: 'asc',
            },
          },
        },
      });

      if (!task) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "任务不存在",
        });
      }

      return task;
    }),

  getStats: protectedProcedure
    .input(z.object({
      courseId: z.string(),
    }))
    .query(async ({ ctx, input }) => {
      const tasks = await ctx.db.task.findMany({
        where: { courseId: input.courseId },
        include: {
          steps: {
            include: {
              completions: true,
            },
          },
        },
      });

      const totalTasks = tasks.length;
      const completedTasks = tasks.filter(task => 
        task.steps.every(step => 
          step.status === "COMPLETED" || 
          step.completions.some(c => c.userId === ctx.session.user.id)
        )
      ).length;

      return {
        totalTasks,
        completedTasks,
        completionRate: totalTasks ? Math.round((completedTasks / totalTasks) * 100) : 0,
      };
    }),

  getById: protectedProcedure
    .input(z.object({
      taskId: z.string(),
    }))
    .query(async ({ ctx, input }) => {
      const task = await ctx.db.task.findUnique({
        where: { id: input.taskId },
        include: {
          steps: {
            orderBy: {
              orderIndex: 'asc',
            },
          },
          course: {
            select: {
              id: true,
              title: true,
              teacherId: true,
            },
          },
        },
      });

      if (!task) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "任务不存在",
        });
      }

      return task;
    }),

  getWithCourse: protectedProcedure
    .input(z.object({
      courseId: z.string(),
      taskId: z.string(),
    }))
    .query(async ({ ctx, input }) => {
      const task = await ctx.db.task.findFirst({
        where: { 
          id: input.taskId,
          courseId: input.courseId,
        },
        include: {
          steps: {
            orderBy: {
              orderIndex: 'asc',
            },
          },
          course: {
            select: {
              id: true,
              title: true,
            },
          },
        },
      });

      if (!task) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "任务不存在或不属于该课程",
        });
      }

      return task;
    }),
}); 